package com.rosense.server.config;

import java.io.File;
import java.nio.file.Path;
import java.nio.file.WatchEvent;
import java.rmi.Naming;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import javax.servlet.ServletContext;

import net.dotool.file.SimpleWatch;
import net.dotool.file.WatchTools;

import org.dom4j.Document;
import org.dom4j.Element;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;

import com.rosense.client.rpc.IRPCServer;
import com.rosense.client.rpc.RpcIpBean;
import com.rosense.commons.LangUtils;
import com.rosense.commons.xml.Dom4jUtils;

public class HostConfigMgr {
	private static HostConfigMgr config = new HostConfigMgr();

	private HostConfigMgr() {
		WebApplicationContext webApplicationContext = null;
		while (webApplicationContext == null) {
			webApplicationContext = ContextLoader.getCurrentWebApplicationContext();
			if (webApplicationContext == null) {
				try {
					TimeUnit.SECONDS.sleep(1);
					continue;
				} catch (InterruptedException e) {
				}
			}
			ServletContext servletContext = webApplicationContext.getServletContext();
			final String filePath = servletContext.getRealPath("config") + File.separator + "hosts.xml";
			HostCaches.jarPath = servletContext.getRealPath("") + File.separator + "linux-monitor.jar";

			/**
			 * 监控配置文件，发送变化的时候重新加载
			 */
			WatchTools.watchFile(filePath, new SimpleWatch() {
				public void onModify(WatchEvent<?> event, Path currentPath) {
					loadConfig(filePath);
				}
			}).start();
			loadConfig(filePath);
		}
	}

	/**
	 * 加载配置文件
	 */
	private void loadConfig(String filePath) {
		try {
			Document document = Dom4jUtils.createDocument(new File(filePath));
			Element rootEle = document.getRootElement();
			HostCaches.params.put("host", rootEle.attributeValue("host"));
			HostCaches.params.put("port", rootEle.attributeValue("port"));
			HostCaches.params.put("second", rootEle.attributeValue("second"));
			HostCaches.params.put("path", rootEle.attributeValue("path"));
			List<Element> tableList = rootEle.elements("host");
			List<String> tmp = new ArrayList<String>(HostCaches.hostMap.keySet());
			for (Element ele : tableList) {
				HostBean hostBean = HostCaches.hostMap.get(ele.attributeValue("name"));
				if (hostBean == null) {
					hostBean = new HostBean(ele);
					HostCaches.hostMap.put(hostBean.name, hostBean);
				} else {
					hostBean.refresh(ele);
				}
				tmp.remove(hostBean.name);
			}
			for (String k : tmp) {
				HostCaches.hostMap.remove(k);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 同步信息到客户端
	 */
	public void syncClient() {
		new Thread() {
			public void run() {
				Map<String, String> params = HostCaches.params;
				for (String name : HostCaches.hostMap.keySet()) {
					try {
						HostBean host = HostCaches.hostMap.get(name);
						host.checkTime();
						System.out.println("start syn " + name + " timeout:" + host.timeout);
						if (!host.timeout) {
							IRPCServer<RpcIpBean> server = (IRPCServer<RpcIpBean>) Naming.lookup("rmi://" + name + ":34567/rpc");
							RpcIpBean rpcBean = new RpcIpBean(params.get("host"), params.get("port"), LangUtils.toInt(params.get("second"), 0));
							server.set(rpcBean);
						}
					} catch (Exception e) {
						System.out.println(e.getMessage());
					}
				}
			}
		}.start();
	}

	public void syncStop() {
		new Thread() {
			@Override
			public void run() {
				for (String name : HostCaches.hostMap.keySet()) {
					try {
						HostBean host = HostCaches.hostMap.get(name);
						host.checkTime();
						System.out.println("start syn " + name + " timeout:" + host.timeout);
						if (!host.timeout) {
							IRPCServer<RpcIpBean> server = (IRPCServer<RpcIpBean>) Naming.lookup("rmi://" + name + ":34567/rpc");
							RpcIpBean rpcBean = new RpcIpBean();
							rpcBean.setStop(true);
							server.set(rpcBean);
						}
					} catch (Exception e) {
						System.out.println(e.getMessage());
					}
				}
			}
		}.start();
	}

	/**
	 * 获取主机信息
	 */
	public HostBean getHostBean(String name) {
		return HostCaches.hostMap.get(name);
	}

	public Map<String, HostBean> getHostCacheMap() {
		return HostCaches.hostMap;
	}

	public static HostConfigMgr getConfig() {
		return config;
	}
}
